﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Threading;
namespace SerialIO
{
    class Presenter
    {
        public static RoutedCommand SetPort { get; set; }
        public static RoutedCommand Send { get; set; }
        public CommandBindingCollection myCommands { get; set; }
        SerialCom serial;
        public Collection<String> PortList
        {
            get
            {
                return serial.GetPorts();
            }
        }
        public Presenter()
        {
            myCommands = new CommandBindingCollection();
            myCommands.Add(new CommandBinding(SetPort = new RoutedCommand(), SetPortHandler, CanSetPort));
            myCommands.Add(new CommandBinding(Send = new RoutedCommand(), SendCommandHandler, CanSendCommand));
            serial = new SerialCom();
        }

        private void CanSendCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = false;
            if (serial._port != null)
            {
                e.CanExecute = true;
            }

        }

        /// <summary>
        /// Handles the Send command
        /// </summary>
        /// <param name="sender">the templated parent upon which the command is registered</param>
        /// <param name="e">the arguments for the event</param>
        private void SendCommandHandler(object sender, ExecutedRoutedEventArgs e)
        {
            try
            {
                var command = (Commands)e.Parameter;
                serial.send(command);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fel!");
            }
        }
        /// <summary>
        /// Handles the SetPort command
        /// </summary>
        /// <param name="sender">the templated parent upon which the command is registered</param>
        /// <param name="e">the arguments for the event</param>
        private void SetPortHandler(object sender, ExecutedRoutedEventArgs args)
        {
            var port = args.Parameter as String;
            if (port != null)
            {
                this.serial.SetPort(port, DataReceivedHandler);
            }
        }
        /// <summary>
        /// Decides if the caller (bound to the SetPort command) can be triggered
        /// </summary>
        /// <param name="sender">the templated parent upon which the command is registered</param>
        /// <param name="e">the arguments for the event</param>
        private void CanSetPort(object sender, CanExecuteRoutedEventArgs args)
        {
            args.CanExecute = true;
        }

        private void DataReceivedHandler(
                          object sender,
                          SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            byte data;
            String s = "";
            while (sp.BytesToRead > 0)
            {
                s += (char) sp.ReadChar();
                Thread.Sleep(20);
            }
            LogConsole.WriteLine(String.Format("Data received: {0}", s));
            
            
        }

        internal void ExitGraceful(object sender, EventArgs e)
        {
            serial.stop();
        }
    }
     
}
